package com.ssy.lingxi.member.merchant.serviceimpl.web;

import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.member.MemberLevelTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberStatusEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.PasswordUtil;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.AddMemberBO;
import com.ssy.lingxi.member.merchant.model.bo.ProcessBO;
import com.ssy.lingxi.member.merchant.model.bo.UpdatePlatformMemberBO;
import com.ssy.lingxi.member.merchant.model.bo.WorkflowTaskResultBO;
import com.ssy.lingxi.member.merchant.model.constant.*;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.MemberTypeAndRoleIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.MemberTypeIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.RoleIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.*;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.*;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.PlatformAddMemberPageItemsVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.PlatformMemberMaintenanceMemberDetailVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.PlatformMemberQuerySearchConditionVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.PlatformPageQueryMemberVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.MemberValidateVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.response.WorkFlowStepVO;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.*;
import com.ssy.lingxi.member.merchant.service.feign.IPayFeignService;
import com.ssy.lingxi.member.merchant.service.feign.IPlatformTemplateFeignService;
import com.ssy.lingxi.member.merchant.service.feign.IProductFeignService;
import com.ssy.lingxi.member.merchant.service.feign.IWorkflowFeignService;
import com.ssy.lingxi.member.merchant.service.web.IPlatformMemberMaintenanceService;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 平台后台 - 会员维护相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2020-07-07
 */
@Service
public class PlatformMemberMaintenanceServiceImpl implements IPlatformMemberMaintenanceService {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private IBaseMemberCacheService memberCacheService;

    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private MemberTypeRepository memberTypeRepository;

    @Resource
    private RoleRepository roleRepository;

    @Resource
    private BaseLevelConfigRepository baseLevelConfigRepository;

    @Resource
    private CountryCodeRepository countryCodeRepository;

    @Resource
    private IBasePlatformProcessService basePlatformProcessService;

    @Resource
    private IBaseMemberHistoryService baseMemberHistoryService;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private IBaseMemberRegisterDetailService baseMemberRegisterDetailService;

    @Resource
    private IBaseMemberInnerService memberInnerService;

    @Resource
    private IWorkflowFeignService baseWorkflowService;

    @Resource
    private IPayFeignService payFeignService;

    @Resource
    private IPlatformTemplateFeignService platformTemplateFeignService;

    @Resource
    private IBaseMemberLevelConfigService baseMemberLevelConfigService;

    @Resource
    private IProductFeignService productFeignService;

    /**
     * 获取分页查询页面中各个查询条件下拉选择框的内容
     * @param headers Http头部信息
     * @return 操作结果
     */
    @Override
    public Wrapper<PlatformMemberQuerySearchConditionVO> getPageCondition(HttpHeaders headers) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);

        PlatformMemberQuerySearchConditionVO conditionVO = new PlatformMemberQuerySearchConditionVO();
        //内部状态
        conditionVO.setInnerStatus(PlatformInnerStatusEnum.toDropdownList());

        //外部状态
        conditionVO.setOuterStatus(Stream.of(MemberOuterStatusEnum.TO_PLATFORM_VERIFY, MemberOuterStatusEnum.PLATFORM_VERIFYING, MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED, MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED).map(e -> new DropdownItem(e.getCode(), e.getMsg())).collect(Collectors.toList()));

        //会员状态
        conditionVO.setStatus(Stream.of(MemberStatusEnum.NORMAL, MemberStatusEnum.FROZEN).map(s -> new DropdownItem(s.getCode(), s.getMsg())).collect(Collectors.toList()));

        //会员类型
        conditionVO.setMemberTypes(memberTypeRepository.findAll().stream().sorted(Comparator.comparingInt(MemberTypeDO::getTypeEnum)).map(memberTypeDO -> new MemberTypeIdAndNameVO(memberTypeDO.getId(), MemberTypeEnum.getCodeMessage(memberTypeDO.getTypeEnum()))).collect(Collectors.toList()));

        //会员角色（按照Id升序排序）
        conditionVO.setMemberRoles(roleRepository.findAll().stream().filter(r -> !r.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())).map(roleDO -> new RoleIdAndNameVO(roleDO.getId(), roleDO.getRoleName())).sorted(Comparator.comparingLong(RoleIdAndNameVO::getRoleId)).collect(Collectors.toList()));

        //注册来源
        conditionVO.setSource(MemberRegisterSourceEnum.toPlatformDropdownList());

        //会员等级
        conditionVO.setMemberLevels(baseMemberLevelConfigService.listSubMemberLevels(loginUser.getMemberId(), loginUser.getMemberRoleId()));

        return Wrapper.success(conditionVO);
    }

    /**
     * 平台后台 - 会员维护 - 分页模糊查询会员审核信息
     * @param queryVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<PlatformPageQueryMemberVO>> pageMembers(HttpHeaders headers, PlatformMemberQueryVO queryVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        //使用Specification构造模糊查询条件并查询
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            //上级为平台
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));

            //不查询由会员创建的，未提交平台审核的数据（此时数据的内部状态为 MemberInnerStatusEnum.REGISTERING.getCode()
            list.add(criteriaBuilder.notEqual(root.get("innerStatus").as(Integer.class), PlatformInnerStatusEnum.REGISTERING.getCode()));

            //会员角色
            if(NumberUtil.notNullOrZero(queryVO.getRoleId())) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), queryVO.getRoleId()));
            }

            //内部状态
            if(NumberUtil.notNullOrZero(queryVO.getInnerStatus())) {
                list.add(criteriaBuilder.equal(root.get("innerStatus").as(Integer.class), queryVO.getInnerStatus()));
            }

            //外部状态
            if(NumberUtil.notNullOrZero(queryVO.getOuterStatus())) {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), queryVO.getOuterStatus()));
            }

            //会员状态
            if(NumberUtil.notNullOrZero(queryVO.getStatus())) {
                list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), queryVO.getStatus()));
            }

            //注册起始时间
            if(StringUtils.hasLength(queryVO.getStartDate())) {
                LocalDateTime startDate = LocalDateTime.parse(queryVO.getStartDate().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), startDate));
            }

            //注册结束时间
            if(StringUtils.hasLength(queryVO.getEndDate())) {
                LocalDateTime endDate = LocalDateTime.parse(queryVO.getEndDate().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), endDate));
            }

            //会员名称
            Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
            if(StringUtils.hasLength(queryVO.getName())) {
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + queryVO.getName().trim() + "%"));
            }

            //注册来源
            if(NumberUtil.notNullOrZero(queryVO.getSource())) {
                list.add(criteriaBuilder.equal(subMemberJoin.get("source").as(Integer.class), queryVO.getSource()));
            }

            //会员等级
            if(NumberUtil.notNullOrZero(queryVO.getLevel())) {
                Join<Object, Object> levelRightJoin = root.join("levelRight", JoinType.LEFT);
                list.add(criteriaBuilder.equal(levelRightJoin.get("level").as(Integer.class), queryVO.getLevel()));
            }

            //会员类型
            if(NumberUtil.notNullOrZero(queryVO.getMemberTypeId())) {
                Join<Object, Object> memberTypeJoin = root.join("subRole", JoinType.LEFT);
                list.add(criteriaBuilder.equal(memberTypeJoin.get("memberType").get("id").as(Long.class), queryVO.getMemberTypeId()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable page = PageRequest.of(queryVO.getCurrent() - 1, queryVO.getPageSize(), Sort.by("id").descending());
        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, page);

        List<MemberRelationDO> content = pageList.getContent();
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), content.stream().map(relationDO -> {
            PlatformPageQueryMemberVO memberVO = new PlatformPageQueryMemberVO();
            memberVO.setMemberId(relationDO.getSubMemberId());
            memberVO.setValidateId(relationDO.getId());
            memberVO.setRoleId(relationDO.getSubRoleId());
            memberVO.setName(relationDO.getSubMember().getName());
           // memberVO.setMemberTypeId(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            memberVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            memberVO.setRoleName(relationDO.getSubRole().getRoleName());
            memberVO.setSource(relationDO.getSubMember().getSource());
            memberVO.setSourceName(MemberRegisterSourceEnum.getCodeMessage(relationDO.getSubMember().getSource()));
            memberVO.setRegisterTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));

            //从关联的角色查找等级
            memberVO.setLevel(relationDO.getLevelRight().getLevel());
            memberVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            memberVO.setStatus(relationDO.getStatus());
            memberVO.setStatusName(MemberStatusEnum.getCodeMessage(relationDO.getStatus()));
            memberVO.setInnerStatus(relationDO.getInnerStatus());
            memberVO.setInnerStatusName(PlatformInnerStatusEnum.getCodeMsg(relationDO.getInnerStatus()));
            memberVO.setOuterStatus(relationDO.getOuterStatus());
            memberVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()));
            return memberVO;
        }).collect(Collectors.toList())));
    }


    /**
     * 获取会员导入Excel模板
     * @param request Http请求
     * @param response Http响应（文件流）
     */
    @Override
    public void getMemberImportFile(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setCharacterEncoding("utf-8");
            response.sendError(404, "此功能尚未完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导入会员
     * @param headers Http头部信息
     * @param excelFile 上传的文件流
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> importMembers(HttpHeaders headers, MultipartFile excelFile) {
        return Wrapper.fail(ResponseCode.MC_MS_FEATURE_NOT_COMPLETE);
    }

    /**
     * 查询导入批次列表
     * @param headers HttpHeaders信息
     * @return 查询结果
     */
    @Override
    public Wrapper<List<String>> getImportBatchNo(HttpHeaders headers) {
        return Wrapper.fail(ResponseCode.MC_MS_FEATURE_NOT_COMPLETE);
    }

    /**
     * 根据批次号，删除批量导入的会员
     * @param headers HttpHeaders信息
     * @param memberVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> deleteMembersByBatchNo(HttpHeaders headers, BatchDeleteMemberVO memberVO) {
        return Wrapper.fail(ResponseCode.MC_MS_FEATURE_NOT_COMPLETE);
    }

    /**
     * 获取新增会员页面内容
     * @param headers HttpHeaders信息
     * @return 查询结果
     */
    @Override
    public Wrapper<PlatformAddMemberPageItemsVO> getAddMemberPageItems(HttpHeaders headers) {
        memberCacheService.checkUserFromCache(headers);
        PlatformAddMemberPageItemsVO itemsVO = new PlatformAddMemberPageItemsVO();

        //会员类型
        List<MemberTypeIdAndNameVO> memberTypeIdAndNameVOList = memberTypeRepository.findAll().stream().map(c -> new MemberTypeIdAndNameVO(c.getId(), MemberTypeEnum.getCodeMessage(c.getTypeEnum()))).collect(Collectors.toList());
        itemsVO.setMemberTypes(memberTypeIdAndNameVOList);

        List<DropdownItem> itemList = countryCodeRepository.findAll().stream().map(c -> new DropdownItem(c.getId().intValue(), c.getCode())).collect(Collectors.toList());
        itemsVO.setCountryCodes(itemList);

        //固定审核流程
        List<WorkFlowStepVO> steps = new ArrayList<>();
        WorkFlowStepVO stepVO = new WorkFlowStepVO();
        stepVO.setStep(1);
        stepVO.setRoleName(MemberStringEnum.BUSINESS_ROLE.getName());
        stepVO.setStepName(MemberStringEnum.APPLY_FOR_REGISTER.getName());
        steps.add(stepVO);

        stepVO = new WorkFlowStepVO();
        stepVO.setStep(2);
        stepVO.setRoleName(MemberStringEnum.PLATFORM_ROLE_NAME.getName());
        stepVO.setStepName(MemberStringEnum.MEMBER_VALIDATE.getName());
        steps.add(stepVO);
        itemsVO.setVerifySteps(steps);

        itemsVO.setCurrentStep(1);

        return Wrapper.success(itemsVO);
    }

    /**
     * 根据会员类型，查询角色列表
     * @param headers HttpHeader信息
     * @param idVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<RoleIdAndNameVO>> getAddMemberPageRoles(HttpHeaders headers, MemberTypeIdVO idVO) {
        MemberTypeDO memberTypeDO = memberTypeRepository.findById(idVO.getMemberTypeId()).orElse(null);
        if(memberTypeDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_TYPE_DOES_NOT_EXIST);
        }

        List<RoleDO> roleDOList = roleRepository.findByMemberType(memberTypeDO);

        return Wrapper.success(roleDOList.stream().filter(roleDO -> !roleDO.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())).map(roleDO -> new RoleIdAndNameVO(roleDO.getId(), roleDO.getRoleName())).sorted(Comparator.comparingLong(RoleIdAndNameVO::getRoleId)).collect(Collectors.toList()));
    }

    /**
     * 新增会员页面，根据会员类型和角色，查询等级列表
     * @param headers         HttpHeader信息
     * @param typeAndRoleIdVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<LevelAndTagVO>> getAddMemberPageLevels(HttpHeaders headers, MemberTypeAndRoleIdVO typeAndRoleIdVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);

        List<LevelAndTagVO> result = baseMemberLevelConfigService.listSubMemberLevels(loginUser.getMemberId(), loginUser.getMemberRoleId(), typeAndRoleIdVO.getRoleId(), typeAndRoleIdVO.getMemberTypeId());

        if(CollectionUtils.isEmpty(result)) {
            return Wrapper.success(Stream.of(new LevelAndTagVO(0, "")).collect(Collectors.toList()));
        }

        return Wrapper.success(result);
    }

    /**
     * 新增会员页面，根据选择的角色，返回会员注册资料信息
     *
     * @param headers HttpHeader信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberConfigGroupVO>> getAddMemberPageMemberConfigItems(HttpHeaders headers, RoleIdVO idVO) {
        memberCacheService.needLoginFromManagePlatform(headers);
        RoleDO roleDO = roleRepository.findById(idVO.getRoleId()).orElse(null);
        if(roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        return Wrapper.success(baseMemberRegisterDetailService.groupMemberConfig(new ArrayList<>(roleDO.getConfigs())));
    }

    /**
     * 新增会员
     * @param headers HttpHeaders信息
     * @param memberVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> addMember(HttpHeaders headers, PlatformAddMemberVO memberVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        //幂等校验
        if(memberCacheService.existRegisterKey(memberVO.getPhone(), false)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_PHONE_EXISTS);
        }

        if(StringUtils.hasLength(memberVO.getEmail()) && memberCacheService.existRegisterKey(memberVO.getEmail(), false)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_EMAIL_EXISTS);
        }

        memberCacheService.setRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);

        //查询平台会员和平台角色
        MemberDO platformMemberDO = memberRepository.findFirstByAccount(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT);
        if (platformMemberDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_REGISTER_BEFORE_PLATFORM_MEMBER_CREATE);
        }

        RoleDO platformRoleDO = platformMemberDO.getRoles().stream().filter(r -> r.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())).findFirst().orElse(null);
        if (platformRoleDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_REGISTER_BEFORE_PLATFORM_MEMBER_CREATE);
        }

        MemberTypeDO memberTypeDO = memberTypeRepository.findById(memberVO.getMemberTypeId()).orElse(null);
        if(memberTypeDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_TYPE_DOES_NOT_EXIST);
        }

        RoleDO roleDO = roleRepository.findById(memberVO.getRoleId()).orElse(null);
        if(roleDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        //通过角色查询会员业务类型
        MemberBusinessTypeDO memberBusinessTypeDO = roleDO.getBusinessType();
        if(memberBusinessTypeDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_BUSINESS_TYPE_DOES_NOT_EXIST);
        }

        CountryCodeDO countryCodeDO = countryCodeRepository.findById(memberVO.getCountryCodeId()).orElse(null);
        if(countryCodeDO == null) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_COUNTRY_CODE_DOES_NOT_EXIST);
        }

        //检查手机号是否已经存在
        if(memberUserRepository.existsByRelTypeAndPhone(MemberRelationTypeEnum.OTHER.getCode(), memberVO.getPhone())) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_PHONE_EXISTS);
        }

        //会员名称和详细信息
        List<MemberRegisterDetailDO> registerDetails = new ArrayList<>();
        Wrapper<String> checkResult = baseMemberRegisterDetailService.checkMemberRegisterDetail(memberVO.getDetail(), new ArrayList<>(roleDO.getConfigs()), registerDetails, memberVO.getPhone());
        if(checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        //检查名称是否已经存在
        String memberName = checkResult.getData();
        if(StringUtils.hasLength(memberName) && memberRepository.existsByName(memberName)) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_NAME_REGISTERED);
        }

        //判断邮箱（如果非空）是否存在
        if(StringUtils.hasLength(memberVO.getEmail()) && memberUserRepository.existsByRelTypeAndEmail(MemberRelationTypeEnum.OTHER.getCode(), memberVO.getEmail())) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_EMAIL_EXISTS);
        }

        String md5Password;
        try {
            md5Password = PasswordUtil.instance().passwordToMd5String(ServiceConfig.PLATFORM_ADD_MEMBER_DEFAULT_PASSWORD);
        } catch (Exception e) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(ResponseCode.MD5_ERROR);
        }

        //根据角色查找平台会员审核流程的Key
        Wrapper<ProcessBO> processResult = basePlatformProcessService.findRolePlatformProcess(roleDO);
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        //新增会员
        AddMemberBO memberBO = new AddMemberBO();
        memberBO.setPlatformProcess(processResult.getData());
        memberBO.setUpperMember(platformMemberDO);
        memberBO.setUpperRole(platformRoleDO);
        memberBO.setRoleDO(roleDO);
        memberBO.setMemberTypeDO(memberTypeDO);
        memberBO.setBusinessTypeDO(memberBusinessTypeDO);
        memberBO.setRegisterDetails(registerDetails);
        memberBO.setName(memberName);
        memberBO.setCountryCode(countryCodeDO.getCode());
        memberBO.setPhone(memberVO.getPhone());
        //通过注册添加的都是商家，手机号即账号
        memberBO.setAccount(memberVO.getPhone());
        memberBO.setPassword(md5Password);
        memberBO.setEmail(StringUtils.hasLength(memberVO.getEmail()) ? memberVO.getEmail() : "");
        //平台创建下级会员，外部审核记录的操作角色为平台角色
        memberBO.setOperatorRoleName(platformRoleDO.getRoleName());

        memberBO.setSource(MemberRegisterSourceEnum.FROM_PLATFORM_IMPORT);
        memberBO.setInnerStatus(PlatformInnerStatusEnum.TO_BE_COMMIT.getCode());
        memberBO.setLevel(memberVO.getLevel());

        Wrapper<?> addResult = memberInnerService.addPlatformMember(memberBO);
        if(addResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            memberCacheService.deleteRegisterKey(memberVO.getPhone(), memberVO.getEmail(), false);
            return Wrapper.fail(addResult.getCode(), addResult.getMessage());
        }

        return Wrapper.success();
    }

    /**
     * 新增会员页面，查询用户基本信息
     *
     * @param headers    HttpHeaders信息
     * @param validateVO 接口参数
     * @return 会员基本信息
     */
    @Override
    public Wrapper<PlatformMemberMaintenanceMemberDetailVO> getMemberDetail(HttpHeaders headers, MemberValidateVO validateVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        PlatformMemberMaintenanceMemberDetailVO detailVO = new PlatformMemberMaintenanceMemberDetailVO();
        List<WorkFlowStepVO> outerValidateSteps = new ArrayList<>();
        WorkFlowStepVO stepVO = new WorkFlowStepVO();
        stepVO.setStep(1);
        stepVO.setStepName("申请会员");
        stepVO.setRoleName(relationDO.getSubRoleName());
        outerValidateSteps.add(stepVO);

        stepVO = new WorkFlowStepVO();
        stepVO.setStep(2);
        stepVO.setStepName("审核会员");
        stepVO.setRoleName(loginUser.getMemberRoleName());
        outerValidateSteps.add(stepVO);
        Integer currentOuterSteps = (relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode()) || relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode())) ? 2 : 1;
        detailVO.setOuterVerifySteps(outerValidateSteps);
        detailVO.setCurrentOuterStep(currentOuterSteps);

        detailVO.setMemberId(relationDO.getSubMemberId());
        detailVO.setValidateId(relationDO.getId());
        detailVO.setName(relationDO.getSubMember().getName());
        detailVO.setMemberTypeId(relationDO.getSubRole().getMemberType().getId());
        detailVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
        detailVO.setRoleId(relationDO.getSubRoleId());
        detailVO.setRoleName(relationDO.getSubRoleName());
        detailVO.setLevelId(relationDO.getLevelRight() == null ? 0L : (relationDO.getLevelRight().getLevelConfig() == null ? 0L : relationDO.getLevelRight().getLevelConfig().getId()));
        detailVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
        detailVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
        detailVO.setCountryCode(relationDO.getSubMember().getCountryCode());
        CountryCodeDO countryCodeDO = countryCodeRepository.findFirstByCode(detailVO.getCountryCode());
        if(countryCodeDO == null) {
            detailVO.setCountryCodeId(0L);
        } else {
            detailVO.setCountryCodeId(countryCodeDO.getId());
        }

        detailVO.setPhone(relationDO.getSubMember().getPhone());
        detailVO.setEmail(relationDO.getSubMember().getEmail());

        //detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetail(relationDO.getSubMember(), MemberDetailVersionEnum.USING));
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetail(relationDO.getSubMember()));


        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * 修改会员
     *
     * @param headers  Http头部信息
     * @param memberVO 接口参数
     * @return 修改结果
     */
    @Override
    public Wrapper<Void> updateMemberDetail(HttpHeaders headers, PlatformUpdateMemberVO memberVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);
        MemberRelationDO relationDO = relationRepository.findById(memberVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubMemberId().equals(memberVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //只有待提交审核、审核不通过才能修改信息
        if(!(relationDO.getInnerStatus().equals(PlatformInnerStatusEnum.VERIFY_NOT_PASSED.getCode()) || relationDO.getInnerStatus().equals(PlatformInnerStatusEnum.TO_BE_COMMIT.getCode()))) {
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_UPDATE_OR_DELETE_SUB_MEMBER_HAS_BEEN_COMMIT);
        }

        MemberTypeDO memberTypeDO = memberTypeRepository.findById(memberVO.getMemberTypeId()).orElse(null);
        if(memberTypeDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_TYPE_DOES_NOT_EXIST);
        }

        RoleDO roleDO = roleRepository.findById(memberVO.getRoleId()).orElse(null);
        if(roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        //如果已经有相同角色
        if(!roleDO.getId().equals(relationDO.getSubRoleId()) && relationDO.getSubMember().getRoles().stream().anyMatch(r -> r.getId().equals(roleDO.getId()))) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_ALREADY_HAVE_THE_ROLE);
        }

        //通过角色查询会员业务类型
        MemberBusinessTypeDO memberBusinessTypeDO = roleDO.getBusinessType();
        if(memberBusinessTypeDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_BUSINESS_TYPE_DOES_NOT_EXIST);
        }

        CountryCodeDO countryCodeDO = countryCodeRepository.findById(memberVO.getCountryCodeId()).orElse(null);
        if(countryCodeDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_COUNTRY_CODE_DOES_NOT_EXIST);
        }

        //通过level查询等级配置
        if(memberVO.getLevel() != null && !memberVO.getLevel().equals(0)) {
            List<BaseLevelConfigDO> baseLevelConfigDOList = baseLevelConfigRepository.findByMemberLevelTypeEnumAndStatusAndRole(MemberLevelTypeEnum.PLATFORM.getCode(), EnableDisableStatus.ENABLE.getCode(), roleDO);
            if (!CollectionUtils.isEmpty(baseLevelConfigDOList) && baseLevelConfigDOList.stream().noneMatch(baseLevelConfigDO -> baseLevelConfigDO.getLevel().equals(memberVO.getLevel()))) {
                return Wrapper.fail(ResponseCode.MC_MS_MEMBER_LEVEL_DOES_NOT_EXIST);
            }
        }

        //要修改的会员的管理员账号（用于判断手机号是否已经注册）
        MemberUserDO userDO = relationDO.getSubMember().getUsers().stream().filter(memberUserDO -> memberUserDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if(userDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        //检查手机号是否已经存在
        Specification<MemberUserDO> specification = (Specification<MemberUserDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.notEqual(root.get("member").as(MemberDO.class), relationDO.getMember()));
            list.add(criteriaBuilder.notEqual(root.get("id").as(Long.class), userDO.getId()));
            list.add(criteriaBuilder.equal(root.get("phone").as(String.class), memberVO.getPhone()));
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        if(memberUserRepository.count(specification) > 0) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_PHONE_EXISTS);
        }

        //判断邮箱（如果非空）是否存在
        if(StringUtils.hasLength(memberVO.getEmail())) {
            specification = (Specification<MemberUserDO>) (root, query, criteriaBuilder) -> {
                List<Predicate> list = new ArrayList<>();
                list.add(criteriaBuilder.notEqual(root.get("member").as(MemberDO.class), relationDO.getMember()));
                list.add(criteriaBuilder.notEqual(root.get("id").as(Long.class), userDO.getId()));
                list.add(criteriaBuilder.equal(root.get("email").as(String.class), memberVO.getEmail().trim()));
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            };

            if(memberUserRepository.count(specification) > 0) {
                return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_EMAIL_EXISTS);
            }
        }

        //会员名称和详细信息
        List<MemberRegisterDetailDO> memberRegisterDetails = new ArrayList<>();
        Wrapper<String> checkResult = baseMemberRegisterDetailService.checkMemberRegisterDetail(memberVO.getDetail(), relationDO.getSubMember().getRoles().stream().flatMap(role -> role.getConfigs().stream()).collect(Collectors.toList()), memberRegisterDetails, memberVO.getPhone());
        if(checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        //检查名称是否已经存在
        String memberName = checkResult.getData();
        if(StringUtils.hasLength(memberName) && memberRepository.existsByNameAndIdNot(memberName, relationDO.getSubMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_NAME_REGISTERED);
        }

        //修改完之后，变为待提交状态
        if(relationDO.getInnerStatus().equals(PlatformInnerStatusEnum.VERIFY_NOT_PASSED.getCode())) {
            Wrapper<WorkflowTaskResultBO> taskResult = baseWorkflowService.startMemberProcess(relationDO.getValidateTask().getProcessKey(), relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getId());
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            relationDO.setInnerStatus(taskResult.getData().getInnerStatus());
            relationDO.setOuterStatus(MemberOuterStatusEnum.TO_PLATFORM_VERIFY.getCode());
            relationDO.getValidateTask().setTaskId(taskResult.getData().getTaskId());
            relationRepository.saveAndFlush(relationDO);
        }

        //修改会员
        UpdatePlatformMemberBO updatePlatformMemberBO = new UpdatePlatformMemberBO();
        updatePlatformMemberBO.setRelationDO(relationDO);
        updatePlatformMemberBO.setRoleDO(roleDO);
        updatePlatformMemberBO.setMemberTypeDO(memberTypeDO);
        updatePlatformMemberBO.setLevel(memberVO.getLevel());
        updatePlatformMemberBO.setRegisterDetails(memberRegisterDetails);
        updatePlatformMemberBO.setName(memberName);
        updatePlatformMemberBO.setCountryCode(countryCodeDO.getCode());
        updatePlatformMemberBO.setPhone(memberVO.getPhone());
        updatePlatformMemberBO.setEmail(memberVO.getEmail());

        return memberInnerService.updatePlatformMember(updatePlatformMemberBO);
    }


    /**
     * 冻结/解冻会员
     *
     * @param statusVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> changeMemberStatus(HttpHeaders headers, ChangeMemberStatusVO statusVO) {
        UserLoginCacheDTO loginUser = memberCacheService.needLoginFromManagePlatform(headers);

        //查询平台会员和平台角色
        MemberDO platformMemberDO = memberRepository.findFirstByAccount(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT);
        if (platformMemberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_REGISTER_BEFORE_PLATFORM_MEMBER_CREATE);
        }

        RoleDO platformRoleDO = platformMemberDO.getRoles().stream().filter(r -> r.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())).findFirst().orElse(null);
        if (platformRoleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_REGISTER_BEFORE_PLATFORM_MEMBER_CREATE);
        }

        MemberRelationDO relationDO = relationRepository.findById(statusVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(statusVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        relationDO.setStatus(statusVO.getStatus());
        relationRepository.saveAndFlush(relationDO);

        //记录外部操作记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getRole().getRoleName(), statusVO.getStatus().equals(MemberStatusEnum.FROZEN.getCode()) ? MemberValidateHistoryOperationEnum.FREEZE_MEMBER : MemberValidateHistoryOperationEnum.UNFREEZE_MEMBER, MemberStatusEnum.getCodeMessage(relationDO.getStatus()), statusVO.getRemark());

        //通知支付服务，冻结-解冻资金账户
        payFeignService.notifyUpdateMemberAssetAccount(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId(), relationDO.getRelType(), relationDO.getStatus());

        //如果是冻结会员，通知商品服务，下架所有商品
        if(relationDO.getStatus().equals(MemberStatusEnum.FROZEN.getCode())) {
            productFeignService.asyncNotifyToOffProducts(relationDO.getSubMemberId(), relationDO.getSubRoleId(), relationDO.getSubRole().getMemberType().getTypeEnum());
        }

        //通知店铺模板服务
        int templateServiceStatus;
        if(relationDO.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            templateServiceStatus = 1;
        } else {
            templateServiceStatus = 0;
        }
        platformTemplateFeignService.notifyMemberStatusChangedAsync(relationDO.getSubMemberId(), relationDO.getSubRoleId(), templateServiceStatus);

        return Wrapper.success();
    }

    /**
     * 删除会员
     * @param headers Http头部信息
     * @param validateVO 接口参数
     * @return 删除结果
     */
    @Override
    public Wrapper<Void> deleteMember(HttpHeaders headers, MemberValidateVO validateVO) {
        memberCacheService.needLoginFromManagePlatform(headers);

        MemberRelationDO relationDO = relationRepository.findById(validateVO.getValidateId()).orElse(null);
        if(relationDO == null || !relationDO.getSubMemberId().equals(validateVO.getMemberId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //todo 确认删除条件
        if(relationRepository.existsBySubMemberIdAndSubRoleIdAndRelType(relationDO.getSubMemberId(), relationDO.getSubRoleId(), MemberRelationTypeEnum.OTHER.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_CANNOT_DELETE_OTHER_SUB_MEMBER);
        }

        return memberInnerService.deletePlatformMemberAndRole(relationDO);
    }
}
